package cn.iocoder.yudao.module.system.api.user;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.EmailInfo;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.encryption.EncryptionUtil;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.api.user.dto.*;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.SystemGroupCount;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserUpdateReqVO;
import cn.iocoder.yudao.module.system.convert.user.UserConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.AUTH_LOGIN_USER_EXIST;

/**
 * Admin 用户 API 实现类
 *
 * @author 芋道源码
 */
@Service
public class AdminUserApiImpl implements AdminUserApi {

    @Resource
    private AdminUserService userService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private OperateLogService operateLogService;
    @Resource
    private DeptService deptService;
    @Value("${spring.profiles.active}")
    private String active;
    @Override
    public AdminUserRespDTO getUser(Long id) {
        AdminUserDO user = userService.getUser(id);
        return UserConvert.INSTANCE.convert1(user);
    }

    @Async
    @Override
    public void sendHtmlMail(EmailInfo emailInfo){
//        MailUtils.sendHtmlMail(emailInfo);
        emailInfo.setEnvironment(active);
        HttpUtils.doPost("http://127.0.0.1:8085/demo/task/sendMail",JSONObject.toJSONString(emailInfo));
    }
    @Override
    public AdminUserRespDTO getUser(String mobile) {
        AdminUserDO user = userService.getUsersBymobile(mobile);
        return UserConvert.INSTANCE.convert1(user);
    }

    @Override
    public AdminUserRespDTO getUserTenantId(String mobile, String type) {
        AdminUserDO user = userService.getUserTenantId(mobile,type);
        return UserConvert.INSTANCE.convert1(user);
    }

    @Override
    public AdminUserRespDTO getUserByMobile(String mobile, Long companyId) {
        AdminUserDO user = userService.selectByPhone(mobile,companyId);
        return UserConvert.INSTANCE.convert1(user);
    }

    @TenantIgnore
    @Override
    public AdminUserRespDTO getUserNoTenant(String mobile) {
        AdminUserDO user = userService.getUsersBymobileNoTenant(mobile);
        return UserConvert.INSTANCE.convert1(user);
    }

    @TenantIgnore
    @Override
    public AdminUserRespDTO getNoTenantUser(String username) {
        AdminUserDO user = userService.getUsersBymobile(username);
        return UserConvert.INSTANCE.convert1(user);
    }


    @Override
    public List<AdminUserRespDTO> getUsersByDeptIds(Collection<Long> deptIds) {
        List<AdminUserDO> users = userService.getUsersByDeptIds(deptIds);
        return UserConvert.INSTANCE.convertList4(users);
    }

    @Override
    public void deleteUser(Long id) {
        userService.deleteUser(id);
    }

    @Override
    public PageResult<AdminUserRespDTO> getUsersPage(UserPageVO userPageVO) {
        UserPageReqVO userPageReqVO=new UserPageReqVO();
        BeanUtils.copyProperties(userPageVO,userPageReqVO);
        PageResult<AdminUserDO> users=userService.getUserPage(userPageReqVO);
        return UserConvert.INSTANCE.convertPage(users);
    }

    @Override
    public List<AdminUserRespDTO> getUsersByPostIds(Collection<Long> postIds) {
        List<AdminUserDO> users = userService.getUsersByPostIds(postIds);
        return UserConvert.INSTANCE.convertList4(users);
    }

    @Override
    public Map<Long, AdminUserRespDTO> getUserMap(Collection<Long> ids) {
        Map<Long, AdminUserDO> userMap = userService.getUserMap(ids);
        return UserConvert.INSTANCE.convertMap4(userMap);
    }

    @Override
    @TenantIgnore
    public List<Long> getUserIdsByTenant(Long tenantId) {
        List<AdminUserDO> adminUserDOList=userService.getUsersByTenantId(tenantId);
        List<Long> ids=new ArrayList<>();
        for (AdminUserDO adminUserDO:adminUserDOList) {
                ids.add(adminUserDO.getId());
        }
        return ids;
    }

    @Override
    public void validUsers(Set<Long> ids) {
        userService.validUsers(ids);
    }

    @Override
    public void updateUsersPhone(Long id, String mobile,Integer unrealFlag) {
        UserUpdateReqVO userUpdateReqVO=new UserUpdateReqVO();
        userUpdateReqVO.setId(id);
        if(StringUtils.isNotBlank(mobile)){
            if(mobile.length()<=20){
                userUpdateReqVO.setMobile(EncryptionUtil.desEncrypt(mobile));
            }else{
                userUpdateReqVO.setMobile(mobile);
            }
            userUpdateReqVO.setUsername(mobile);
        }
        if(null!=unrealFlag){
            userUpdateReqVO.setUnrealFlag(unrealFlag);
        }
        userService.updateUser(userUpdateReqVO);
    }

    @Override
    public void updateUser(UserUpateReqDTO userUpateReqDTO) {
        UserUpdateReqVO userUpdateReqVO=new UserUpdateReqVO();
        BeanUtils.copyProperties(userUpateReqDTO,userUpdateReqVO);
        userService.updateUser(userUpdateReqVO);
    }

    @Override
    public void updateSonUser(UserUpateReqDTO userUpateReqDTO) {
        UserUpdateReqVO userUpdateReqVO=new UserUpdateReqVO();
        BeanUtils.copyProperties(userUpateReqDTO,userUpdateReqVO);
        if(StringUtils.isNotBlank(userUpateReqDTO.getUserName())){
            userUpdateReqVO.setUsername(userUpateReqDTO.getUserName());
        }
        userService.updateSonUser(userUpdateReqVO);
    }

    @Override
    public boolean isAdminUser(LoginUser loginUser) {
        Set<String> rolecodes=loginUser.getRoleCodes();
        for (String code:rolecodes) {
            if(code.equals(RoleCodeEnum.TENANT_ADMIN.getCode())) {
                return true;
            }
        }
        return  false;
    }

    @Override
    public Long createCompanyUser(UserCreateReqDTO reqVO) {
        UserCreateReqVO userCreateReqVO=new UserCreateReqVO();
        BeanUtils.copyProperties(reqVO,userCreateReqVO);
        return userService.createCompanyUser(userCreateReqVO);
    }

    @Override
    public Long createCompanySonUser(UserCreateReqDTO reqVO,Long tenantId) {
        UserCreateReqVO userCreateReqVO=new UserCreateReqVO();
        BeanUtils.copyProperties(reqVO,userCreateReqVO);
        Long userCountByMobile = userService.getUserCountByMobile(reqVO.getMobile());
        if(null!=userCountByMobile && userCountByMobile>0){
            throw exception(AUTH_LOGIN_USER_EXIST);
        }
        return userService.createCompanySonUser(userCreateReqVO,tenantId);
    }

    @Override
    public Long getUserCountByMobile(String mobile) {
        Long userCountByMobile = userService.getUserCountByMobile(mobile);
        return null==userCountByMobile?0:userCountByMobile;
    }

    @Override
    public PageResult<UserPageItemRespDTO> getCompanyUsersPage(UserPageReqDTO userPageVO) {
        UserPageReqVO userPageReqVO=new UserPageReqVO();
        BeanUtils.copyProperties(userPageVO,userPageReqVO);
        userPageReqVO.setId(SecurityFrameworkUtils.getLoginUserId());
        // 获得用户分页列表
        PageResult<AdminUserDO> pageResult = userService.getUserPage(userPageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return new PageResult<>(pageResult.getTotal()); // 返回空
        }

        // 获得拼接需要的数据
        Collection<Long> deptIds = convertList(pageResult.getList(), AdminUserDO::getDeptId);
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(deptIds);
        // 拼接结果返回
        List<UserPageItemRespDTO> userList = new ArrayList<>(pageResult.getList().size());
        pageResult.getList().forEach(user -> {
            UserPageItemRespDTO respVO = UserConvert.INSTANCE.convert1(user);
            respVO.setDeptName(user.getDeptName());
            userList.add(respVO);
        });
        return new PageResult<UserPageItemRespDTO>(userList, pageResult.getTotal());
    }

    @Override
    public PageResult<UserPageItemRespDTO> getOperateUsersPage(UserPageReqDTO userPageVO) {
        UserPageReqVO userPageReqVO=new UserPageReqVO();
        BeanUtils.copyProperties(userPageVO,userPageReqVO);
        userPageReqVO.setId(SecurityFrameworkUtils.getLoginUserId());
        userPageReqVO.setTenantId(2L);
        // 获得用户分页列表
        PageResult<AdminUserDO> pageResult = userService.getUserPageByTenantId(userPageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return new PageResult<>(pageResult.getTotal()); // 返回空
        }

        // 获得拼接需要的数据
        Collection<Long> deptIds = convertList(pageResult.getList(), AdminUserDO::getDeptId);
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(deptIds);
        // 拼接结果返回
        List<UserPageItemRespDTO> userList = new ArrayList<>(pageResult.getList().size());
        pageResult.getList().forEach(user -> {
            UserPageItemRespDTO respVO = UserConvert.INSTANCE.convert1(user);
            respVO.setDeptName(user.getDeptName());
            userList.add(respVO);
        });
        return new PageResult<UserPageItemRespDTO>(userList, pageResult.getTotal());
    }

    @Override
    public List<SystemGroupCountDTO> getOperateLogGroupCont(String startDate, String endDate) {
        List<SystemGroupCount> oList = operateLogService.getOperateLogGroupCont(startDate, endDate);
        List<SystemGroupCountDTO> list=new ArrayList<>();
        if(CollectionUtils.isNotEmpty(oList)){
            oList.stream().forEach(m->{
                SystemGroupCountDTO d=new SystemGroupCountDTO();
                BeanUtils.copyProperties(m,d);
                list.add(d);
            });
        }
        return list;
    }
}
